import sys
import numpy as np
import random
import xlwt

workbook = xlwt.Workbook(encoding='utf-8', style_compression=0)

# 获取表格页
s1 = workbook.add_sheet('问题三数据1', cell_overwrite_ok=False)
style = xlwt.XFStyle()

oneline = ["零配件检测1", "零配件检测2", "零配件检测3",
           "零配件检测4", "零配件检测5", "零配件检测6",
           "零配件检测7", "零配件检测8", "半成品检测1",
           "半成品检测2", "半成品检测3", "半成品拆解1",
           "半成品拆解2", "半成品拆解3", "成品检测", "成品拆解", "最大利润率","次品率"]

for j in range(len(oneline)):
    s1.write(0, j, oneline[j])


# 次品率
NUM = 1e3#实验次数
p_ = 0.1
h = 0.5
p = 0
#更据p_随机生成次品率
def rand() :
    global p
    a = 1e5*p_*(1 - h)
    b = 1e5*p_*(1 + h)
    p = random.randint(a,b) / 1e5


# 购买单价
a = [2, 8, 12, 2, 8, 12, 8, 12]
f1 = 22
f2 = 22
f3 = 20
f4 = 88

num1 = [1]
num2 = [1]
maxM = [0]
maxy0 = []
maxy1 = []
maxy2 = [0]
maxz1 = []
maxz2 = [0]
# 检测成本
b0 = [1, 1, 2, 1, 1, 2, 1, 2]
# 装配成本
c = 8
# 检测成本
b1 = 4
b2 = 6
# 拆解费用
d1 = 6
d2 = 10

N = 1e2
isno = [0, 1]

y0 = []  # 9
y1 = []  # 4
y2 = [0]
z1 = []  # 4
for i in range(9):
    y0.append(0)
    y1.append(0)
    z1.append(0)
    maxy0.append(0)
    maxy1.append(0)
    maxz1.append(0)

z2 = [0]


#
def check(t0):
    t1 = t2 = t3 = 0
    if t0 == 1:
        t2 = 2
        t3 = 3
    elif t0 == 2:
        t2 = 1
        t3 = 3
    elif t0 == 3:
        t2 = 1
        t3 = 2
    return t2, t3


q1 = (p + (1 - p) * p)
q2 = (p + (1 - p) * p + (1 - p) * (1 - p) * p)
P3 = p * y0[7] * y0[8] + q1 * (y0[7] * (1 - y0[8]) + y0[8] * (1 - y0[7])) + q2 * (1 - y0[7]) * (1 - y0[8])


def P(t0):
    t1 = t2 = t3 = 0
    if t0 == 1:
        t1 = 1
        t2 = 2
        t3 = 3
    elif t0 == 2:
        t1 = 4
        t2 = 5
        t3 = 6
    return p * y0[t1] * y0[t2] * y0[t3] + q1 * (
                y0[t1] * y0[t2] * (1 - y0[t3]) + y0[t1] * y0[t3] * (1 - y0[t2]) + y0[t2] * y0[t3] * (
                    1 - y0[t1])) + q2 * (
                y0[t1] * (1 - y0[t2]) * (1 - y0[t3]) + y0[t2] * (1 - y0[t1]) * (1 - y0[t3]) + y0[t3] * (1 - y0[t1]) * (
                    1 - y0[t2]))


#

def o1(t0):
    t2, t3 = check(t0)
    p123 = P(t0)
    return p123 * (1 - p123) * p * (y1[t2] * y1[t3]) * (1 - y1[t0])


def o2(t0):
    t2, t3 = check(t0)
    _p = P(t2)
    p_ = P(t3)
    return (_p + (1 - _p) * p_ + (1 - _p) * (1 - p_) * p) * (1 - y1[t2]) * (1 - y1[t3]) * y1[t0]


p2 = p * y1[2] * y1[1] * y1[3] + o1(1) + o1(2) + o1(3) + o2(3) + o2(1) + o2(2) + ((P(1) +
                                                                                   (1 - P(1)) * P(2)) + (1 - P(1)) * (
                                                                                              1 - P(2)) * P(3) + (
                                                                                              1 - P(1)) * (1 - P(2)) * (
                                                                                              1 - P(3)) * p) * (
                 1 - y1[2]) * (1 - y1[1]) * (1 - y1[3])


def Result(x):
    u1 = [0]
    u2 = [0]
    l1 = max(y0[1], y0[2], y0[3])
    l2 = max(y0[4], y0[5], y0[6])
    l3 = max(y1[1], y1[2], y1[3])
    x11 = x[0] * (1 - y0[1]) * (1 - y0[2]) * (1 - y0[3]) + (1 - p) * x[1] * l1
    x12 = x[3] * (1 - y0[4]) * (1 - y0[5]) * (1 - y0[6]) + (1 - p) * x[3] * l2
    x13 = x[6] * (1 - y0[7]) * (1 - y0[8]) + (1 - p) * x[6] * (y0[7] + y0[8] - y0[7] * y0[8])
    x2 = x11 * (1 - y1[1]) * (1 - y1[2]) * (1 - y1[3]) + (1 - p) * (x[0]) * l3

    for i in range(8):
        u1 += x[i] * a[i]
        u2 += x[i] * b0[i] * y0[i + 1]

    u3 = 8 * (x11 + x12 + x13)
    u4 = 4 * (x11 * y1[1] + x12 * y1[2] + x13 * y1[3])
    u5 = d1 * (x11 * y1[1] * z1[1] + x12 * y1[2] * z1[2] + x13 * y1[3] * z1[3])
    u6 = x11 * P(1) * f1 * z1[1] + x12 * P(2) * f2 * z1[2] + x13 * P3 * f3 * z1[3] + x2 * p2 * f4 * z2[0]
    R = 200 * x[1] - x[1] * p2 * (1 - y2[0]) - (
                u1 + u2 + u3 + u4 + c * x2 + b2 * x2 * y2[0] + u5 + d2 * x2 * y2[0] * z2[0] + 40 * x2 * p2 * (
                    1 - y2[0])) + u6

    S = u1 + u2 + u3 + u4 + c * x2 + b2 * x2 * y2[0] + u5 + d2 * x2 * y2[0] * z2[0] + 40 * x2 * p2 * (1 - y2[0])

    W = S / R

    if W > maxM:
        maxM[0] = W
        for i in range(8):
            maxy0[i] = y0[i + 1]
        for i in range(3):
            maxy1[i] = y1[i + 1]
            maxz1[i] = z1[i + 1]
        maxy2[0] = y2[0]
        maxz2[0] = z2[0]


def test4():
    for i in range(2):
        for j in range(2):
            y2[0] = i
            z2[0] = j
            # 解关于x0的非齐次线性方程,构造系数矩阵A,和常量B
            u1 = 1 - p * y0[1]
            u2 = 1 - p * y0[2]
            u3 = 1 - p * y0[3]
            u4 = 1 - p * y0[4]
            u5 = 1 - p * y0[5]
            u6 = 1 - p * y0[6]
            u7 = 1 - p * y0[7]
            u8 = 1 - p * y0[8]
            e1 = (1 - p * y1[1]) * u1
            e2 = (1 - p * y1[2]) * u4
            e3 = (1 - p * y1[3]) * u7
            A = np.array([[u1, -u2, 0, 0, 0, 0, 0, 0],
                          [u1, 0, -u3, 0, 0, 0, 0, 0],
                          [0, 0, 0, u4, -u5, 0, 0, 0],
                          [0, 0, 0, 0, u5, -u6, 0, 0],
                          [0, 0, 0, 0, 0, 0, u7, -u8],
                          [e1, 0, 0, -e2, 0, 0, 0, 0],
                          [0, 0, 0, e2, 0, 0, -e3, 0],
                          [2, 8, 12, 2, 8, 12, 8, 12]
                          ])

            B = np.array([0, 0, 0, 0, 0, 0, 0, N])
            x0 = np.linalg.solve(A, B)
            Result(x0)


# 枚举z1
def test3():
    for i2 in range(2):
        for j2 in range(2):
            for k2 in range(2):
                z1[1] = isno[i2]
                z1[2] = isno[j2]
                z1[3] = isno[k2]
                test4()


# 枚举y1
def test2(pos2):
    for i1 in range(2):
        for j1 in range(2):
            for k1 in range(2):
                y1[1] = isno[i1]
                y1[2] = isno[j1]
                y1[3] = isno[k1]
                test3()


# 枚举y0
def test1(pos1):
    #生成随机数
    if pos1 == 9:
        test2(1)
        return
    for i in range(0, 2):
        y0[pos1] = isno[i]
        test1(pos1 + 1)

for i in range(10):
    rand()
    test1(1)
# 将数据保存至表格中
    linemax = maxy0[0:8] + maxy1[0:3] + maxz1[0:3] + maxz2[0:] + maxy2[0:]
    linemax.append(str(maxM[0]))

    linemax.append(str(p))

    for j in range(len(linemax)):
        s1.write(i + 1, j, linemax[j])

    maxM[0] = 0


workbook.save('question4_2_date.xls')